package com.itheima.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.autoconfig.template.HuanXinTemplate;
import com.itheima.commons.utils.Constants;
import com.itheima.dubbo.api.*;
import com.itheima.model.domain.Question;
import com.itheima.model.domain.UserInfo;
import com.itheima.model.dto.RecommendUserDto;
import com.itheima.model.mongo.RecommendUser;
import com.itheima.model.mongo.Visitors;
import com.itheima.model.vo.ErrorResult;
import com.itheima.model.vo.NearUserVo;
import com.itheima.model.vo.PageResult;
import com.itheima.model.vo.TodayBest;
import com.itheima.server.exception.BusinessException;
import com.itheima.server.interceptor.UserHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class TanhuaService {
    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @Value("${tanhua.default.recommend.users}")
    private String recommendUser;

    @DubboReference
    private UserLikeApi userLikeApi;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private HuanXinTemplate template;
    @Autowired
    private MessageService messageService;
    @DubboReference
    private FriendApi friendApi;
    @DubboReference
    private UserLocationApi userLocationApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    /*今日佳人*/
    public TodayBest todayBest(Long userId) {
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        if (recommendUser == null) {
            return null;
        }
        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
        if (userInfo == null) {
            return null;
        }
        return TodayBest.init(userInfo, recommendUser);
    }

    /* *//*推荐好友列表信息*//*
    public PageResult recommendation(RecommendUserDto dto) {
        //查询该用户被推荐的用户列表
        List<RecommendUser> recommendUserList = recommendUserApi.pageWithScore(UserHolder.getUserId(), dto.getPage(), dto.getPagesize());
        if (null == recommendUserList) {

            return new PageResult(dto.getPage(), dto.getPagesize(), 0, null);
        }
        //根据该用户信息，以及推荐的用户id查询筛选用户详情
        UserInfo userInfo = new UserInfo();
        if (null != dto.getAge()) {
            userInfo.setAge(dto.getAge());
        }
        if (!StringUtils.isEmpty(dto.getGender())) {
            userInfo.setGender(dto.getGender());
        }
        List<Long> ids = CollUtil.getFieldValues(recommendUserList, "userId", Long.class);//从这个集合中抽取id属性封装成集合
        Map<Long, UserInfo> map = userInfoApi.findByIds(ids,userInfo);
        //封装对象
        List<TodayBest> todayBests = new ArrayList<TodayBest>();
        for (RecommendUser recommendUser : recommendUserList) {
            UserInfo info = map.get(recommendUser.getUserId());
            if(info!=null){
                todayBests.add(TodayBest.init(info, recommendUser));
            }
        }
        //构造返回值
        return new PageResult(dto.getPage(),dto.getPagesize(),todayBests.size(),todayBests);
    }*/
    /*推荐好友列表信息*/
    public PageResult recommendation(RecommendUserDto dto) {
        //查询该用户被推荐的用户列表
        Map<Long, RecommendUser> map = recommendUserApi.pageWithScore(UserHolder.getUserId());
        if (null == map) {
            return new PageResult(dto.getPage(), dto.getPagesize(), (long) 0, null);
        }
        //根据该用户信息，以及推荐的用户id查询筛选用户详情
        UserInfo userInfo = new UserInfo();
        if (null != dto.getAge()) {
            userInfo.setAge(dto.getAge());
        }
        if (!StringUtils.isEmpty(dto.getGender())) {
            userInfo.setGender(dto.getGender());
        }
        Set<Long> set = map.keySet();
//       ArrayList<Set<Long>> ids = (ArrayList<Set<Long>>) CollectionUtil.toList(set);
        ArrayList<Long> ids = new ArrayList<>(set);
        PageResult page = userInfoApi.findByIds(ids, userInfo, dto.getPage(), dto.getPagesize());
        //封装todayBests对象
        List<UserInfo> items = (List<UserInfo>) page.getItems();
        List<TodayBest> todayBests = new ArrayList<TodayBest>();
        for (UserInfo item : items) {
            RecommendUser recommendUser = map.get(item.getId());
            todayBests.add(TodayBest.init(item, recommendUser));
        }
        page.setItems(todayBests);
        //构造返回值
        return page;
    }

    public TodayBest personalInfo(Long userId) {
        //查询要查看的用户详情
        UserInfo userInfo = userInfoApi.findById(userId);
        //查询两个人的缘分之（recommend）
        RecommendUser recommendUser = recommendUserApi.quryByHuanxin(UserHolder.getUserId(), userInfo.getId());
        //构造访客数据，调用api保存
        Visitors visitors = new Visitors();
        visitors.setUserId(userId);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(recommendUser.getScore());
        visitorsApi.save(visitors);

        return TodayBest.init(userInfo, recommendUser);

    }

    //      查看陌生人问题,id是陌生人id
    public String strangerQuestion(Long userId) {
        Question question = questionApi.findByUserId(userId);
        if (question == null) {
            return "你喜欢java吗";
        }
        return question.getTxt();
    }

    //回复陌生人信息(userid是陌生人id)
    public void replyQuestions(Long userId, String reply) {
        //查询当前用户id的详细信息
        Long currentUserId = UserHolder.getUserId();//我的id
        UserInfo userInfo = userInfoApi.findById(currentUserId);//查询我的详情
        //封装数据（我的）
        Map<String, Object> map = new HashMap<>();
        map.put("userId", currentUserId);
        map.put("huanXinId", Constants.HX_USER_PREFIX + currentUserId);
        map.put("nickname", userInfo.getNickname());
        map.put("strangerQuestion", strangerQuestion(userId));
        map.put("reply", reply);
        String jsonString = JSON.toJSONString(map);//转换成字符串格式进行传输
        //发送数据
        Boolean aBoolean = template.sendMsg(Constants.HX_USER_PREFIX + userId, jsonString);
        if (!aBoolean){
            throw new BusinessException(ErrorResult.error());
        }

    }

    public List<TodayBest> queryCardsList() {
        //调用推荐查询数据列表（排除喜欢/不喜欢的用户，数量限制10）
        List<RecommendUser> recommendUserList = recommendUserApi.quryCardList(UserHolder.getUserId(), 10);
        /*//判断数据是否存在（不存在就构造默认数据）
        if (CollUtil.isEmpty(recommendUserList)) {
            recommendUserList = new ArrayList<>();
            String[] split = recommendUser.split(",");
            for (String s : split) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Convert.toLong(s));
                recommendUser.setToUserId(UserHolder.getUserId());
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                recommendUserList.add(recommendUser);
            }
        }*/
        //判断数据是否存在，不存在就报错
        if(CollUtil.isEmpty(recommendUserList)){
            throw new BusinessException(ErrorResult.recommendError());
        }
        //构造vo
        List<Long> userIds = CollUtil.getFieldValues(recommendUserList, "userId", Long.class);
        Map<Long, UserInfo> userInfoApiByIds = userInfoApi.findByIds(userIds, null);
        List<TodayBest> res = new ArrayList<>();
        for (RecommendUser user : recommendUserList) {
            UserInfo userInfo = userInfoApiByIds.get(user.getUserId());
            res.add(TodayBest.init(userInfo, user));
        }
        return res;
    }

    /*喜欢用户*/
    public void love(Long likeUserId) {
        //调用api，保存喜欢数据(mongodb)
        Boolean res = userLikeApi.saveOrUpdate(UserHolder.getUserId(), likeUserId, true);
        if (!res) {
            throw new BusinessException(ErrorResult.error());
        }
        //操作redis，写入喜欢的数据，删除不喜欢的数据
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        //是否是双向喜欢(判断对方是否喜欢你)
        if (isLike(likeUserId)) {
            //添加好友
            messageService.contacts(likeUserId);
        }
    }

    /*不喜欢用户*/
    public void notlove(Long likeUserId) {
        //调用api，保存喜欢数据(mongodb)
        Boolean res = userLikeApi.saveOrUpdate(UserHolder.getUserId(), likeUserId, false);
        if (!res) {
            throw new BusinessException(ErrorResult.error());
        }
        //操作redis，写入喜欢的数据，删除不喜欢的数据
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        //是否是好友
        if (friendApi.isFriend(UserHolder.getUserId(),likeUserId)) {
            //删除好友
            messageService.unContacts(likeUserId);
        }
    }

    /*抽取的方法，判断对方是否喜欢你*/
    public boolean isLike(Long userId) {
        return redisTemplate.opsForSet().isMember(Constants.USER_LIKE_KEY + userId, UserHolder.getUserId().toString());
    }

    //搜附近用户信息
    public List<NearUserVo> search(String gender, String distance) {
        List<Long> ids =userLocationApi.queryByLocation(UserHolder.getUserId(),distance);
        if(CollUtil.isEmpty(ids)){
            return new ArrayList<>();
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(gender);
        Map<Long, UserInfo> userInfos = userInfoApi.findByIds(ids, userInfo);
        Collection<UserInfo> values = userInfos.values();
        ArrayList<NearUserVo> nearUserVos = new ArrayList<>();
        for (UserInfo value : values) {
            if(value.getId().equals(UserHolder.getUserId())){
                continue;
                //跳过自己的信息
            }else {
                nearUserVos.add(NearUserVo.init(userInfo));
            }
        }
        return nearUserVos;
    }
}
